package com.jboltai.resource.ai;

import com.jboltai.config.JBoltAIConfig;
import com.jboltai.event.ai.AIEvent;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

/**
 * ai资源中心
 */
public class AIResourceCenter {

    private static final Logger LOGGER = LoggerFactory.getLogger(JBoltAIConfig.LOGGER_NAME);
    private static final ConcurrentHashMap<AIModel, AIResourceGroup> MODEL_RESOURCES = new ConcurrentHashMap<>();

    private static Timer limitResetTimer = new Timer("ai-limit-reset-thread");

    static {

        //每分钟重置一下 各模型的频率限制
        limitResetTimer.scheduleAtFixedRate(new TimerTask() {
            @Override
            public void run() {
                MODEL_RESOURCES.values().forEach(item -> {
                    item.resetResourceLimit();
                });
            }
        }, 0, 1000 * 60);
    }



    /**
     * 添加可用的ai资源
     * @param resource
     */
    public static void register(AIResource resource) {
        MODEL_RESOURCES.computeIfAbsent(resource.getModel(), model -> new AIResourceGroup()).add(resource);
    }

    /**
     * 移除某个ai资源
     * @param resource
     */
    public static void unregister(AIResource resource) {
        AIResourceGroup schedule = MODEL_RESOURCES.get(resource.getModel());
        if (schedule != null) {
            schedule.removeResource(resource);
        }
    }

    /**
     * 根据id 取消资源的注册
     * @param id
     */
    public static void unregister(String id) {
        AIResource resource = getResourceById(id);
        if (resource != null) {
            unregister(resource);
        }
    }


    /**
     * 根据id获取ai资源
     * @param resourceId
     * @return
     */
    public static AIResource getResourceById(String resourceId) {
        Iterator<AIResourceGroup> iterator = MODEL_RESOURCES.values().iterator();
        while (iterator.hasNext()) {
            AIResourceGroup resources = iterator.next();
            AIResource resource = resources.getResource(resourceId);
            if (resource != null) {
                return resource;
            }

        }
        return null;
    }

    /**
     * 从所有注册的资源中，取一个可用的资源
     * @return
     */
    public static AIResource getValidResource(AIEvent event) {
        if (MODEL_RESOURCES.isEmpty()) return null;
        Enumeration<AIModel> keys = MODEL_RESOURCES.keys();
        AIResource resource = null;
        while (keys.hasMoreElements()) {
            AIModel model = keys.nextElement();
            //如果事件有相关输入，但模型不支持，就跳过
            if (event.isTextInput() && !model.isTextInput()) continue;
            if (event.isImageInput() && !model.isImageInput()) continue;
            if (event.isAudioInput() && !model.isAudioInput()) continue;
            if (event.isVideoInput() && !model.isVideoInput()) continue;

            AIResourceGroup resources = MODEL_RESOURCES.get(model);
            resource = resources.getResource(null);
            if (resource != null) {
                return resource;
            }
        }
        return null;
    }


    /**
     * 检测是否有可用的资源
     * @param model
     * @param resourceId
     * @return
     */
    public static boolean checkHasResource(AIModel model, String resourceId) {
        AIResourceGroup resources = MODEL_RESOURCES.get(model);
        if (resources == null) {
            return false;
        }
        return resources.hasResource(resourceId);
    }
    /**
     * 检测是否有可用的资源
     * @param model
     * @return
     */
    public static boolean checkHasResource(AIModel model) {
        AIResourceGroup resources = MODEL_RESOURCES.get(model);
        return resources != null && resources.getResource(null) != null;
    }


    /**
     * 获取哪些模型注册了资源
     * @return
     */
    public static Set<AIModel> getModels() {
        return MODEL_RESOURCES.keySet();
    }

    /**
     *
     * @param model
     * @return
     */
    public static AIResourceGroup getModelResources(AIModel model) {
        return MODEL_RESOURCES.get(model);
    }


    /**
     * 更新资源，主要就是更新频率限制
     * @param resource
     */
    public static void moveResourceToInvalid(AIResource resource) {
        resource.getResourceGroup().moveToInvalid(resource);
    }
    /**
     * 更新资源，主要就是更新频率限制
     * @param resource
     */
    public static void moveResourceToValid(AIResource resource) {
        resource.getResourceGroup().moveToValid(resource);
    }


    /**
     * 获取资源总数
     * @return
     */
    public static int getResourceCount() {
        return MODEL_RESOURCES.values().stream().mapToInt(item -> item.getResourceCount()).sum();
    }

    /**
     * 获取可用资源总数
     * @return
     */
    public static int getValidResourceCount() {
        return MODEL_RESOURCES.values().stream().mapToInt(item -> item.getValidResourceCount()).sum();
    }

    /**
     * 是否有可用的资源
     * @return
     */
    public static boolean hasValidResource() {
        return MODEL_RESOURCES.values().stream().anyMatch(item -> item.getValidResourceCount() > 0);
    }


    /**
     * 获取不可用资源总数
     * @return
     */
    public static int getInvalidResourceCount() {
        return MODEL_RESOURCES.values().stream().mapToInt(item -> item.getInvalidResourceCount()).sum();
    }





}
